/**
 *  mem.h - Memory management.
 *
 *  Copyright (C) 2008-2009 ZhangHu
 *  All rights reserved.
 *  E-MAIL: anmnmnly@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#ifndef __MM_H__
#define __MM_H__


#include "include/types.h"

#ifndef UNIT_DEBUG
#include "include/list.h"
#include "include/irq.h"
#include "hw_mem.h"
#endif


#define MEM_FREE    0x0     /* Block is free */
#define MEM_ALLOC   0x1     /* Block is allocated */

typedef struct page_struct {
    uword_t size;                /* Block size */
    uword_t status;              /* Status that is frre or allocate */
    list_t free_link;            /* Link to the next free block */
    struct page_struct *mem_up;  /* Link to the upper block */
    struct page_struct *mem_down;/* Link to the lower block */
} page_t;

/* some blocks that linked by this struct,
   in which all size is in a certain range */
struct free_struct {
    list_t free_link;   /* pointer to the first block */
    uword_t size;       /* the maxium size in this group block */
};

/* Initialize memory */
void initmem(void);

/* get start address of memory */
word_t get_start_address(void);


/**
 * allocate - Assign a size of 'Size' space for application.
 * This function is the main routine for assignment memory.
 * However, applications do not called it directly. It can use to
 * driver or some parts of kernel.
 */
void *allocate(word_t Size);

/**
 * kmalloc - Assign a size of 'Size' space for application.
 * It calls 'allocate()' directly after turn off interruption.
 * Applictions should use it for assignment memory.
 */
void *kmalloc(word_t Size);

/**
 * reclaim - Reclaiming a block space.
 * This function is the main routine for Reclaiming memory.
 * However, applications do not called it directly. It can use to
 * driver or some parts of kernel.
 */
void reclaim(void *pfree);

/**
 * kfree - Reclaiming a block space.
 * It calls 'free()' directly after turn off interruption.
 * Applictions should use it for Reclaiming memory.
 */
void kfree(void *pfree);

/* kfree - Set all member of a buffer to 'ch' */
void kmemset(void *buffer, char_t ch, uword_t len);

/* Get the start address of memory */
page_t *kgetmemlist(void);


#endif

